#include "config.h"

#include <errno.h>

#define DBG_SUBSYS S_LIBYNET

#include "ynet_net.h"
#include "ynet_rpc.h"
#include "net_global.h"
#include "fence.h"
#include "dbg.h"


static int  __icmp_request(struct list_head *hlist, struct list_head *nlist, int total)
{
	unsigned int ret ;
	int tim = 1, ok;

retry:
	ok = handle_icmp_packs(hlist, total);

#if 0
	if (ok == total && tim++ < 3)
		goto retry;
	else if (tim >= 3) {
		ret = ENONET;
		GOTO(err_ret, ret);
	}
#else 
	if (ok != total) { 
		if (tim++ < 3) {
			goto retry;
	      	 } else {
                        DWARN("arping fail\n");
			ret = ENONET;
			GOTO(err_ret, ret);
		}
	}	

#endif 

	DINFO("arping ok\n");

	del_all_host(hlist);
	del_all_nic(nlist);

	return 0;

err_ret:
	del_all_host(hlist);
	del_all_nic(nlist);

	return ret;
}


int icmp_host(const char *addr)
{

	struct list_head hlist, nlist;
	struct in_addr src;
	char devname[128];
	int ret;
	struct in_addr sin, *dst;
	struct hostinfo *host;

	INIT_LIST_HEAD(&hlist);
	INIT_LIST_HEAD(&nlist);


	sin.s_addr = inet_addr(addr);
	dst = &sin;

	ret = get_nic_info(&nlist);
	if (unlikely(ret)) {
		DWARN("fence arping get nic info failed in this host\n");
		ret = ENONET;
		GOTO(err_ret, ret);
	}

	host = malloc(sizeof(struct hostinfo));
	if (host == NULL) {
		DWARN("fence arping malloc hostinfo error\n");
		return ENOMEM;
	}


	memset(host, 0x00, sizeof(struct hostinfo));

	host->nic_num = 1;
	host->cur_index = -1;
	strcpy(host->hostname, "host");

	host->intf[0].nic = get_src_ip(*dst, &src, &nlist, devname);
	if (host->intf[0].nic == NULL){
		return ENONET;
	}
	else{
		host->intf[0].src = src;
		host->intf[0].dst = *dst;
		host->intf[0].host = host;
	}

	list_add_tail(&host->list, &hlist);

	ret = __icmp_request(&hlist, &nlist, 2);
	if (unlikely(ret))
		GOTO(err_ret, ret);

	return 0;
err_ret:
	return ret;
}
